enum {
	DCUNDEF = 0,
	DCNUM,
	DCSTR,
	DCSTACK
};

enum {
	DCNL = 1
};

struct data {
	void	*data;
	size_t	 nmemb;
	size_t	 mmemb;
	size_t	 size;
};

struct dcnum {
	z_t	v;
	z_t	k;
};

struct dcstr {
	char	*str;
	size_t	 len;
};

struct dcret {
	FILE *prev;
	void *data;
};

union dcent_u {
	struct data	d;
	struct dcnum	n;
	struct dcstr	s;
};

struct dcent {
	union dcent_u u;
	int type;
};

struct dc {
	struct dcent	 reg[256];
	struct data	 stack;
	struct data	 rstack;
	struct data	 str;
	z_t		 k;
	unsigned	 i;
	unsigned	 o;
	int		 flags;
};

void dcinit(struct dc *);
void dcfree(struct dc *);

int dcent_dup(struct dcent *, struct dcent *);
void dcent_free(struct dcent *);
int dcent_pop(struct data *, int, struct dcent *, size_t);
int dcent_push(struct data *, struct dcent *, size_t);

int dcret_push(struct data *, FILE *, void *);
FILE *dcret_pop(struct data *);

int dcnum(struct dc *, FILE *);
int dcstr(struct dc *, FILE *);

int dcprint(struct dc *, FILE *);
int dcprintc(struct dc *, FILE *);
int dcprintst(struct dc *, FILE *);

int dccmp(struct dc *, int *);

void dcneg(struct dc *);
void dcsqrt(struct dc *);

void dcdup(struct dc *);
void dcclr(struct dc *);
void dcpopi(struct dc *);
void dcpushi(struct dc *);
void dcpopk(struct dc *);
void dcpushk(struct dc *);
void dcpopo(struct dc *);
void dcpusho(struct dc *);
void dcpushl(struct dc *);
void dcpushx(struct dc *);
void dcpushz(struct dc *);

void dcadd(struct dc *);
void dcsub(struct dc *);
void dcmul(struct dc *);
void dcdiv(struct dc *);
void dcmod(struct dc *);
void dcpow(struct dc *);
